use std::{cmp::Ordering, io};

/** # 学生成绩表
编写程序，提示用户输入学生个数、学生姓名和他们的成绩（整数），然后按学生成绩的降序打印输出学生的姓名。

- 编写以下方法，如果参数lst中的成绩已经按降序排列好了，则返回true，否则false。
```java
public static boolean isSorted(int[] lst);
```
*/
pub fn student_score_table() {
    println!("请输入学生个数：");

    // 学生数量
    let mut student_count = String::new();
    let student_count = get_student_count(&mut student_count);

    // 学生成绩表
    let mut student_score: Vec<(String, f32)> = vec![];
    for i in 0..student_count {
        student_score.push(get_student_info(i));
    }

    assert_eq!(is_sorted(&student_score), false);

    // 降序排名
    score_desc(&mut student_score);

    assert_eq!(is_sorted(&student_score), true);
    println!("{:?}", student_score);
}

/** 采集学生数量 */
fn get_student_count(student_count: &mut String) -> i32 {
    // 采集用户在命令行中输入的内容
    io::stdin().read_line(student_count).expect("读取失败");
    match student_count.trim().parse::<i32>() {
        Ok(v) => v,
        Err(e) => {
            println!("请输入正确正确的整数！{}", e);
            get_student_count(student_count)
        }
    }
}

/** 采集每个学生的信息 */
fn get_student_info<'a>(i: i32) -> (String, f32) {
    let mut student_info: String = String::new();

    println!("请输入第{i}个学生信息，格式：姓名 成绩");
    io::stdin().read_line(&mut student_info).expect("读取失败");
    let student_info: Vec<&str> = student_info.trim().split(" ").collect();

    let mut name: String = String::from(student_info[0]);
    let score = match student_info[1].trim().parse::<f32>() {
        Ok(v) => v,
        Err(e) => {
            println!("请输入正确正确的整数！{}", e);
            let new_data = get_student_info(i);
            name = new_data.0;
            new_data.1
        }
    };

    (name, score)
}

/** 降序排名 */
fn score_desc(student_score: &mut Vec<(String, f32)>) {
    student_score.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
}

/** 是否已降序排名 */
fn is_sorted(student_score: &Vec<(String, f32)>) -> bool {
    let mut is_sorted = true;
    for i in 0..student_score.len() {
        // 判断前一个人的成绩是否大于等于后一人的成绩
        if i == 0 || student_score[i - 1].1 >= student_score[i].1 {
            continue;
        }

        // 如果判断为非，则判断当前成绩并未降序排名
        is_sorted = false;
        break;
    }

    is_sorted
}
